﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using System.IO;

using SanctusSoftware.Music.ChordSheetEditor.Client;
using SanctusSoftware.Music.Chords;

using Microsoft.Office.Interop.Word;



namespace SanctusSoftware.Music.ChordSheetEditor.Word
{
  public class WordChordSheetEditorPresenter : ChordSheetEditorPresenterBase //<Document>
  {

    #region Const/Readonly

    private global::System.Object missing = global::System.Type.Missing;

    #endregion

    #region Constructor

    public WordChordSheetEditorPresenter(IWordChordSheetEditorHostView hostView, IChordSheetEditorActionView actionView)
      : base(hostView, actionView)
    {


    }

    #endregion

    #region Overrides

    protected override ISentence[] GetTargetSentences(bool copyContentsToNewDocument)
    {

      Sentences sentences = null;

      switch (ActionView.Target)
      {
        case ActionTarget.ThisDocument:
          sentences = ((IWordChordSheetEditorHostView)HostView).CurrentDocument.Sentences;
          break;
        case ActionTarget.NewDocument:

          bool copyPasteMethod = false;
          if (copyPasteMethod)
          {
            if (copyContentsToNewDocument)
            {
              // TODO: Warn about clipboard
              ((IWordChordSheetEditorHostView)HostView).CurrentDocument.Select();
              ((IWordChordSheetEditorHostView)HostView).CurrentDocument.Content.Copy();
            }

            // TODO: Check for Keys Filled Out and Not Identical
            Document doc = ((IWordChordSheetEditorHostView)HostView).GetNewDocument(); //Application.Documents.Add(ref missing, ref missing, ref missing, ref missing);

            if (copyContentsToNewDocument)
            {
              doc.Content.Paste();
              // TODO: Unselect
              sentences = doc.Sentences;
            }
          }
          else
          {


            try
            {

              HostView.AllowScreenUpdating = false;

              // Supposed to work
              // http://social.msdn.microsoft.com/Forums/en/vsto/thread/cc3cf42e-9035-4ae2-87f2-e4296214c29d

              // Some COM Idea - Doesn't Work with 2007
              // http://blogs.msdn.com/pranavwagh/archive/2008/04/03/how-to-do-a-save-copy-as-in-word.aspx

              // How to Copy Styles
              // http://msdn.microsoft.com/en-us/library/aa220324%28office.11%29.aspx

              HostView.Status = "Getting Source Document Contents...";
              Document sourceDocument = ((IWordChordSheetEditorHostView)HostView).CurrentDocument;
              string xml = sourceDocument.Content.WordOpenXML;

              HostView.Status = "Creating Target Document...";
              Document targetDocument = ((IWordChordSheetEditorHostView)HostView).GetNewDocument();
              HostView.Status = "Filling Target Document Contents...";
              targetDocument.Content.InsertXML(xml, ref missing);

              HostView.Status = "Copying Styles to Target Document...";
              DocumentSetupCopier.CopyStyles(sourceDocument, targetDocument);

              HostView.Status = "Copying Page Setup to Target Document...";
              DocumentSetupCopier.CopyPageSetup(sourceDocument, targetDocument);

              sentences = targetDocument.Sentences;

            }
            catch (Exception ex)
            {
              throw;
            }
            finally
            {
              HostView.AllowScreenUpdating = true;
            }

            /*
                        
            // Open XML
            object start = 0;
            object end = 0;

            // Get Current Document's XML
            Range sourceRange = HostView.CurrentDocument.Range(ref start, ref end);
            object unit = WdUnits.wdWord;
            object wordCount = HostView.CurrentDocument.Words.Count;
            sourceRange.MoveEnd(ref unit, ref wordCount);
            string xml = sourceRange.WordOpenXML;
                        
            // Create the New Document
            Document targetDocument = Application.Documents.Add(ref missing, ref missing, ref missing, ref missing);
            Range targetRange = targetDocument.Range(ref start, ref end);
            object transform = missing;
            targetRange.InsertXML(xml, ref transform);
                        
            */






          }
          break;
        case ActionTarget.CurrentSelection:
          sentences = ((IWordChordSheetEditorHostView)HostView).Selection.Sentences;
          break;
        case ActionTarget.CurrentPage:


          //Application.Selection.GoTo What:=wdGoToBookmark, Name:="\Page"
          //Application.Selection.MoveLeft Unit:=wdCharacter, Count:=1

          //Application.Selection.GoTo What:=wdGoToBookmark, Name:="\Page"
          //Application.Selection.MoveRight Unit:=wdCharacter, Count:=1, Extend:=wdExtend

          object what = WdGoToItem.wdGoToBookmark;
          object which = Missing.Value;
          object count = Missing.Value;
          object name = @"\Page";
          ((IWordChordSheetEditorHostView)HostView).Selection.GoTo(ref what, ref which, ref count, ref name); // @"\Page"); // What:=wdGoToBookmark, Name:="\Page"
          sentences = ((IWordChordSheetEditorHostView)HostView).Selection.Sentences;
          break;

        case ActionTarget.SpecifiedPages:
          // http://www.microsoft.com/communities/newsgroups/en-us/default.aspx?dg=microsoft.public.word.vba.customization&tid=067564cf-8420-403d-86ce-d40398d5df5b&cat=en_US_9c17642b-2393-49e4-bef8-3f9464edc915&lang=en&cr=US&sloc=&p=1
          break;

        default:
          break;
      }

      return GetISentenceArray(sentences);

    }

  

    #endregion

    #region Helper Functions

    private static ISentence[] GetISentenceArray(Sentences sentences)
    {

      ISentence[] retSentences = new ISentence[sentences.Count];
      for (int i = 0; i < sentences.Count; i++)
      {
        retSentences[i] = new WordSentence(sentences[i + 1]);
      }
      return retSentences;
    }

    private static ISentence[] GetISentenceArray(Document document)
    {
      return GetISentenceArray(document.Sentences);
    }

    private Document GetDocument(bool copyContentsToNewDocument)
    {
      Document doc = null;

      switch (ActionView.Target)
      {
        case ActionTarget.ThisDocument:
          doc = ((IWordChordSheetEditorHostView)HostView).CurrentDocument;
          break;
        case ActionTarget.NewDocument:
          if (copyContentsToNewDocument)
          {
            // TODO: Warn about clipboard
            ((IWordChordSheetEditorHostView)HostView).CurrentDocument.Select();
            ((IWordChordSheetEditorHostView)HostView).CurrentDocument.Content.Copy();
          }

          // TODO: Check for Keys Filled Out and Not Identical
          doc = ((IWordChordSheetEditorHostView)HostView).GetNewDocument(); //Application.Documents.Add(ref missing, ref missing, ref missing, ref missing);

          if (copyContentsToNewDocument)
          {
            doc.Content.Paste();
            // TODO: Unselect
          }
          break;
        default:
          break;
      }
      return doc;
    }

    private bool CheckReadyToTranspose()
    {
      if (((IWordChordSheetEditorHostView)HostView).CurrentDocument == null)
      {
        // TODO: Disable Buttons
        HostView.ShowMessage("No Document Selected");
        return false;
      }

      // TODO: See if source and target keys are the same

      return true;

    }

    #endregion

  }
}











#region Debug


//void showSoftSentencesButton_Click(object sender, RibbonControlEventArgs e)
//{
//  try
//  {
//    List<string> lines = new List<string>();
//    foreach (Range sentence in Application.ActiveDocument.Sentences)
//    {
//      List<Range> softSentences = SoftSentenceHelper.GetSoftSentences(sentence);
//      foreach (Range softSentence in softSentences)
//      {
//        lines.Add(softSentence.Text);
//      }
//    }
//    //new DebugLinesForm(lines.ToArray()).ShowDialog();
//  }
//  catch (Exception ex)
//  {
//    MessageBox.Show(ex.Message);
//  }
//}

//void showSentencesButton_Click(object sender, RibbonControlEventArgs e)
//{
//  try
//  {
//    List<string> lines = new List<string>();
//    foreach (Range sentence in Application.ActiveDocument.Sentences)
//    {
//      lines.Add(sentence.Text);
//    }
//    //new DebugLinesForm(lines.ToArray()).ShowDialog();
//  }
//  catch (Exception ex)
//  {
//    MessageBox.Show(ex.Message);
//  }
//}


#endregion

#region FUTURE!
/*
    #region Document Properties

    private void SetupCustomDocumentProperties()
    {

      RibbonDropDownItem x = new RibbonDropDownItem();
      x.Label = "Major Key";
      x.Tag = "DOCPROPERTY  \"Major Key\" ";
      Globals.Ribbons.ChordSheetRibbon.insertPropertyGallery.Items.Add(x);
      Globals.Ribbons.ChordSheetRibbon.insertPropertyGallery.Click += new EventHandler<RibbonControlEventArgs>(insertPropertyGallery_Click);

      // http://msdn.microsoft.com/en-us/library/4e0tda25(VS.80).aspx
      //Microsoft.Office.Core.DocumentProperties properties = null;

      //properties = (Microsoft.Office.Core.DocumentProperties)
      //    Globals.ThisDocument.BuiltInDocumentProperties;
      //properties["Subject"].Value = "Whitepaper";


      // Create & Modify Custom Properties: http://msdn.microsoft.com/en-us/library/dhxe2d75(VS.80).aspx




      // Insert Custom Property
      //Selection.Fields.Add Range:=Selection.Range, Type:=wdFieldEmpty, Text:= _
      //"DOCPROPERTY  Key ", PreserveFormatting:=True

    }
    #endregion

    void insertPropertyGallery_Click(object sender, RibbonControlEventArgs e)
    {
      try
      {
        string tag = Globals.Ribbons.ChordSheetRibbon.insertPropertyGallery.SelectedItem.Tag.ToString();
        //MessageBox.Show(tag);
        object a = WdFieldType.wdFieldEmpty;
        object b = true;
        object c = tag;
        Application.Selection.Fields.Add(Application.Selection.Range, ref a, ref c, ref b);
      }
      catch (Exception ex)
      {


      }
    }

    void chordSheetInformationPropertiesButton_Click(object sender, RibbonControlEventArgs e)
    {
      //try
      //{
      //    ChordSheetPropertiesForm f = new ChordSheetPropertiesForm((DocumentProperties)Application.ActiveDocument.CustomDocumentProperties);
      //    if (f.ShowDialog() == DialogResult.OK)
      //    {
      //        // This is probably where the save code should be
      //        Application.ActiveDocument.Content.Fields.Update();
      //    }
      //}
      //catch (Exception ex)
      //{
      //    //ExceptionLogger.Log(ex);
      //    MessageBox.Show(ex.Message);
      //}
    }
    */
#endregion


#region Future Functionality
/*



        private void InsertChordDiagram(string instrument, string tuning, string chordName)
        {

            // http://social.msdn.microsoft.com/Forums/en-US/vsto/thread/5d68fa72-3fd2-49ca-bf4b-dce4c2899839
            // http://www.neodynamic.com/ND/FaqsTipsTricks.aspx?tabid=66&prodid=3&sid=36
            Image x = ChordDiagramManager.GetChordDiagram(instrument, tuning, chordName);

            string tempFile = Path.GetTempFileName();

            x.Save(tempFile, ImageFormat.Png);

            //string fileName = @"C:\temp.png";
            object linkToFile = false;
            object saveWithDocument = true;
            Application.Selection.InlineShapes.AddPicture(tempFile, ref linkToFile, ref saveWithDocument, ref missing);

        }


        #region Event Handler (Chord Diagrams)

        void addChordDiagramsButton_Click(object sender, RibbonControlEventArgs e)
        {

            try
            {

                List<string> songLines = new List<string>();

                foreach (Range sentence in this.Application.ActiveDocument.Sentences)
                {
                    songLines.Add(sentence.Text);
                }

                string[] chords = ChordTransposer.GetChords(songLines.ToArray(), 50, true);

                foreach (string chord in chords)
                {

                    try
                    {
                        InsertChordDiagram("Guitar", "EADGBE", chord);
                    }
                    catch (Exception ex)
                    {
                        // TODO: Somehow alert... should first verify that there is a diagram available

                    }

                }


            }
            catch (Exception ex)
            {
                ExceptionLogger.Log(ex);
                MessageBox.Show("Error: " + ex.Message);
            }

        }

        #endregion


        #region Event Handlers (Download Lyrics)

        void downloadLyricsButton_Click(object sender, RibbonControlEventArgs e)
        {
            try
            {

                

                ExtractLyricsFromWebSiteForm f = new ExtractLyricsFromWebSiteForm();
                if (f.ShowDialog() == DialogResult.OK)
                {
                    Document doc = GetDocument(false);
                    SongLyrics sl = f.SongLyrics;
                    doc.Content.InsertAfter(sl.CompleteSongTextWithHeadings);   // TODO: Insert at cursor 
                }

            }
            catch (Exception ex)
            {
                ExceptionLogger.Log(ex);
                MessageBox.Show(ex.Message);
                Application.StatusBar = "Download Lyrics Failed";
            }
        }

 

        #endregion

*/
#endregion